package com.mgg.payment.service.alipay;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.mgg.common.dto.OrderDTO;
import com.mgg.common.dto.RefundOrderDTO;
import com.mgg.common.util.JsonUtils;
import com.mgg.payment.config.AlipayAccountConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayFundTransToaccountTransferModel;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeRefundModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayFundTransToaccountTransferRequest;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayFundTransToaccountTransferResponse;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;

@Service("aliPayService")
public class AliPayService {

	private Logger log = LoggerFactory.getLogger(getClass());

    @Autowired
    private AlipayAccountConfig alipayAccountConfig;

    /**
     * 预支付
     * @param orderId
     * @param totalAmount
     * @return
     * @throws AlipayApiException
     */
    public AlipayTradeAppPayResponse create(String orderId, BigDecimal totalAmount) throws AlipayApiException {
    	//实例化客户端
    	AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", alipayAccountConfig.getAppId(), 
    			alipayAccountConfig.getAppPrivateKey(), "json", alipayAccountConfig.getCharset(), 
    			alipayAccountConfig.getAlipayPublicKey(), alipayAccountConfig.getSignType());
        
    	//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
        AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
       
        //SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
        AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//        model.setBody("我是测试数据");
        model.setSubject("美乖乖");
        model.setOutTradeNo(orderId);
        model.setTimeoutExpress("30m");
        model.setTotalAmount(totalAmount.toString());
        model.setProductCode("QUICK_MSECURITY_PAY");
        request.setBizModel(model);
        request.setNotifyUrl(alipayAccountConfig.getNotifyUrl());
        
        //这里和普通的接口调用不同，使用的是sdkExecute
        AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);  
        return response;
    }

    /**
     * 支付回调
     * @param requestParams
     * @return
     * @throws AlipayApiException
     */
    public boolean notify(Map<String, Object> requestParams) throws AlipayApiException {
    	//获取支付宝POST过来反馈信息
    	Map<String,String> params = new HashMap<String,String>();
    	for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
    		String name = (String) iter.next();
//    		String[] values = (String[]) requestParams.get(name);
//    		String valueStr = "";
//    		for (int i = 0; i < values.length; i++) {
//    			valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
//    		}
    		//乱码解决，这段代码在出现乱码时使用。
    		//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
    		params.put(name, requestParams.get(name).toString());
    	}
    	
    	//切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
    	boolean flag = AlipaySignature.rsaCheckV1(params, alipayAccountConfig.getAlipayPublicKey(), 
    			alipayAccountConfig.getCharset(), alipayAccountConfig.getSignType());
    	return flag;
    }
    
    
    /**
     * 退款
     * @param refundOrder 
     * @param order
     * @return
     * @throws AlipayApiException
     */
    public boolean refund(RefundOrderDTO refundOrder, OrderDTO order) throws AlipayApiException {
    	AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", alipayAccountConfig.getAppId(), 
    			alipayAccountConfig.getAppPrivateKey(), "json", alipayAccountConfig.getCharset(), 
    			alipayAccountConfig.getAlipayPublicKey(), alipayAccountConfig.getSignType());
    	
    	AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
    	
    	AlipayTradeRefundModel model = new AlipayTradeRefundModel();
    	model.setTradeNo(order.getTradeNo());
    	model.setOutTradeNo(order.getOrderId());
    	model.setRefundAmount(refundOrder.getAmount().toString());
    	model.setOutRequestNo(refundOrder.getRefundNo());
    	model.setRefundReason("正常退款");
    	log.info("【阿里支付】退款, order = {}", JsonUtils.toJson(order));
    			
    	request.setBizModel(model);
    	AlipayTradeRefundResponse response = alipayClient.execute(request);

    	if(response.isSuccess()){
    		return true;
    	} else {
    		log.error("【阿里支付】退款, 退款失败, 网关返回码={}, 网关返回码描述={}, 业务返回码={}, 业务返回码描述={}, orderId={}", 
    				response.getSubCode(), response.getSubMsg(), response.getCode(), response.getMsg(), order.getOrderId());
    		return false;
    	}
    }
    
    /**
     * 转账
     * @param transferMap
     * @return
     * @throws AlipayApiException
     */
    public AlipayFundTransToaccountTransferResponse transfer(Map<String, String> transferMap) throws AlipayApiException {
    	AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", alipayAccountConfig.getAppId(), 
    			alipayAccountConfig.getAppPrivateKey(), "json", alipayAccountConfig.getCharset(), 
    			alipayAccountConfig.getAlipayPublicKey(), alipayAccountConfig.getSignType());
    	
    	AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
    	AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();

    	model.setOutBizNo(transferMap.get("transfer_no"));
    	model.setPayeeType("ALIPAY_LOGONID");
    	model.setPayeeAccount(transferMap.get("account"));
    	model.setAmount(transferMap.get("amount"));
    	model.setPayerShowName("美乖乖");
    	model.setPayeeRealName(transferMap.get("name"));
    	model.setRemark(transferMap.get("remark"));
    	
    	request.setBizModel(model);
    	AlipayFundTransToaccountTransferResponse response = alipayClient.execute(request);
    	return response;
    }
}
